import dash_ag_grid as dag
from dash import Dash, html, Input, Output, Patch, callback
import pandas as pd
import dash_bootstrap_components as dbc

app = Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])

df1 = pd.read_csv('data_amb.csv')
df2 = pd.read_csv('data_stac.csv')
df3 = pd.read_csv('data_children.csv')
df4 = pd.read_csv('data_adult.csv')

width_title = 200
width_column = 100
rowHeight = 25

columnDefsAmb = [
    {"field": "Korpus", 'headerName': 'Корпус', "filter": True, "sortable": True, "floatingFilter": True,
     "pinned": "left", "width": width_title},
    {
        'headerName': 'Посещения',
        'children': [
            {'field': "planPos", 'headerName': 'План', "width": width_column,
             "valueFormatter": {"function": "d3.format('.0f')(params.value)"}, },
            {'field': "factPos", 'headerName': 'Факт', "width": width_column,
             "valueFormatter": {"function": "d3.format('.0f')(params.value)"}, },
            {'field': "percentPos", 'headerName': '%', "width": width_column,
             "valueFormatter": {"function": "d3.format('.2f')(params.value)"}, },
        ]
    },
    {
        'headerName': 'Обращения',
        'children': [
            {'field': "planObr", 'headerName': 'План', "width": width_column,
             "valueFormatter": {"function": "d3.format('.0f')(params.value)"}, },
            {'field': "factObr", 'headerName': 'Факт', "width": width_column,
             "valueFormatter": {"function": "d3.format('.0f')(params.value)"}, },
            {'field': "percentObr", 'headerName': '%', "width": width_column,
             "valueFormatter": {"function": "d3.format('.2f')(params.value)"}, },
        ]
    },
    {
        'headerName': 'Неотложная помощь',
        'children': [
            {'field': "planNeo", 'headerName': 'План', "width": width_column,
             "valueFormatter": {"function": "d3.format('.0f')(params.value)"}, },
            {'field': "factNeo", 'headerName': 'Факт', "width": width_column,
             "valueFormatter": {"function": "d3.format('.0f')(params.value)"}, },
            {'field': "percentNeo", 'headerName': '%', "width": width_column,
             "valueFormatter": {"function": "d3.format('.2f')(params.value)"}, },
        ]
    },
    {
        'headerName': 'Диспансерное наблюдение',
        'children': [
            {'field': "planDn", 'headerName': 'План', "width": width_column,
             "valueFormatter": {"function": "d3.format('.0f')(params.value)"}, },
            {'field': "factDn", 'headerName': 'Факт', "width": width_column,
             "valueFormatter": {"function": "d3.format('.0f')(params.value)"}, },
            {'field': "percentDn", 'headerName': '%', "width": width_column,
             "valueFormatter": {"function": "d3.format('.2f')(params.value)"}, },
        ]
    }
]
columnDefsStac = [
    {"field": "Korpus", 'headerName': 'Корпус', "filter": True, "sortable": True, "floatingFilter": True,
     "pinned": "left", "resizable": False, "width": width_title},
    {
        'headerName': 'Дневной стационар',
        'children': [
            {'field': "planStac", 'headerName': 'План', "width": width_column},
            {'field': "factStac", 'headerName': 'Факт', "width": width_column},
            {'field': "percentStac", 'headerName': '%', "width": width_column},
        ]
    },
    {
        'headerName': 'Стационар на дому',
        'children': [
            {'field': "planStacHome", 'headerName': 'План', "width": width_column},
            {'field': "factStacHome", 'headerName': 'Факт', "width": width_column},
            {'field': "percentStacHome", 'headerName': '%', "width": width_column},
        ]
    }
]
columnDefsChildren = [
    {"field": "Korpus", 'headerName': 'Корпус', "filter": True, "sortable": True, "floatingFilter": True,
     "pinned": "left", "resizable": False, "width": width_title},
    {
        'headerName': 'Профосмотр несовершеннолетних (ПН1)',
        'children': [
            {'field': "planPN1", 'headerName': 'План', "width": width_column},
            {'field': "factPN1", 'headerName': 'Факт', "width": width_column},
            {'field': "percentPN1", 'headerName': '%', "width": width_column},
        ]
    },
    {
        'headerName': 'Диспансеризация детей сирот (ДС2)',
        'children': [
            {'field': "planDS2", 'headerName': 'План', "width": width_column},
            {'field': "factDS2", 'headerName': 'Факт', "width": width_column},
            {'field': "percentDS2", 'headerName': '%', "width": width_column},
        ]
    }
]
columnDefsAdult = [
    {"field": "Korpus", 'headerName': 'Корпус', "filter": True, "sortable": True, "floatingFilter": True,
     "pinned": "left", "resizable": False, "width": width_title},
    {
        'headerName': 'Диспансеризация 1 этап (ДВ4)',
        'children': [
            {'field': "planDV4", 'headerName': 'План', "width": width_column},
            {'field': "factDV4", 'headerName': 'Факт', "width": width_column},
            {'field': "percentDV4", 'headerName': '%', "width": width_column},
        ]
    },
    {
        'headerName': 'Диспансеризация 2 этап (ДВ2)',
        'children': [
            {'field': "planDV2", 'headerName': 'План', "width": width_column},
            {'field': "factDV2", 'headerName': 'Факт', "width": width_column},
            {'field': "percentDV2", 'headerName': '%', "width": width_column},
        ]
    },
    {
        'headerName': 'Профосмотр взрослых (ОПВ)',
        'children': [
            {'field': "planOPV", 'headerName': 'План', "width": width_column},
            {'field': "factOPV", 'headerName': 'Факт', "width": width_column},
            {'field': "percentOPV", 'headerName': '%', "width": width_column},
        ]
    },
    {
        'headerName': 'Углубленная диспансеризация 1 этап (УД1)',
        'children': [
            {'field': "planUD1", 'headerName': 'План', "width": width_column},
            {'field': "factUD1", 'headerName': 'Факт', "width": width_column},
            {'field': "percentUD1", 'headerName': '%', "width": width_column},
        ]
    },
    {
        'headerName': 'Углубленная диспансеризация 2 этап (УД2))',
        'children': [
            {'field': "planUD2", 'headerName': 'План', "width": width_column},
            {'field': "factUD2", 'headerName': 'Факт', "width": width_column},
            {'field': "percentUD2", 'headerName': '%', "width": width_column},
        ]
    }
]

app.layout = html.Div(
    [
        dbc.Alert("Объемные показатели деятельности медицинской организации в системе ОМС", color="light",
                  style={"margin-top": "16px", "text-align": "center"}),
        html.Div(
            [

                dbc.Alert("Амбулаторная помощь", color="primary", style={"margin-top": "16px"}),
                dag.AgGrid(
                    id="row-pinning-bottom-1",
                    enableEnterpriseModules=True,
                    rowData=df1.to_dict("records"),
                    columnDefs=columnDefsAmb,
                    defaultColDef={"editable": True, 'cellRendererSelector': {"function": "rowPinningBottom(params)"}},
                    dashGridOptions={"animateRows": True, "rowHeight": rowHeight, "domLayout": "autoHeight"},
                ),
                dbc.Alert("Стационар-замещающая помощь", color="primary", style={"margin-top": "16px"}),
                dag.AgGrid(
                    id="row-pinning-bottom-2",
                    rowData=df2.to_dict("records"),
                    columnDefs=columnDefsStac,
                    defaultColDef={"editable": True, 'cellRendererSelector': {"function": "rowPinningBottom(params)"}},
                    dashGridOptions={"animateRows": True, "rowHeight": rowHeight, "domLayout": "autoHeight"},
                ),
                dbc.Alert("Диспансеризация детей", color="primary", style={"margin-top": "16px"}),
                dag.AgGrid(
                    id="row-pinning-bottom-3",
                    rowData=df3.to_dict("records"),
                    columnDefs=columnDefsChildren,
                    defaultColDef={"editable": True, 'cellRendererSelector': {"function": "rowPinningBottom(params)"}},
                    dashGridOptions={"animateRows": True, "rowHeight": rowHeight},
                    style={'height': '225px'}
                ),
                dbc.Alert("Диспансеризация взрослых", color="primary", style={"margin-top": "16px"}),
                dag.AgGrid(
                    id="row-pinning-bottom-4",
                    rowData=df4.to_dict("records"),
                    columnDefs=columnDefsAdult,
                    defaultColDef={"editable": True, 'cellRendererSelector': {"function": "rowPinningBottom(params)"}},
                    dashGridOptions={"animateRows": True, "rowHeight": rowHeight},
                    style={'height': '225px'}
                ),
            ],
            style={'margin': "2%"}
        )
    ]
)


@callback(
    Output("row-pinning-bottom-1", "dashGridOptions"),
    Input("row-pinning-bottom-1", "virtualRowData"),
)
def row_pinning_bottom(data):
    dff = df1 if data is None else pd.DataFrame(data)
    sums = dff[["planPos", "factPos", "percentPos",
                "planObr", "factObr", "percentObr",
                "planNeo", "factNeo", "percentNeo",
                "planDn", "factDn", "percentDn",
                ]].sum() if data else \
        {"planPos": 0, "factPos": 0, "percentPos": 0,
         "planObr": 0, "factObr": 0, "percentObr": 0,
         "planNeo": 0, "factNeo": 0, "percentNeo": 0,
         "planDn": 0, "factDn": 0, "percentDn": 0, }

    sum_formatted = {
        "planPos": sums['planPos'],
        "factPos": sums['factPos'],
        "percentPos": round(sums['factPos'] / sums['planPos'] * 100, 2) if sums['planPos'] != 0 else 0,
        "planObr": sums['planObr'],
        "factObr": sums['factObr'],
        "percentObr": round(sums['factObr'] / sums['planObr'] * 100, 2) if sums['planObr'] != 0 else 0,
        "planNeo": sums['planNeo'],
        "factNeo": sums['factNeo'],
        "percentNeo": round(sums['factNeo'] / sums['planNeo'] * 100, 2) if sums['planNeo'] != 0 else 0,
        "planDn": sums['planDn'],
        "factDn": sums['factDn'],
        "percentDn": round(sums['factDn'] / sums['planDn'] * 100, 2) if sums['planDn'] != 0 else 0,
    }
    grid_option_patch = Patch()
    grid_option_patch["pinnedBottomRowData"] = [{"Korpus": "Итого", **sum_formatted}]
    return grid_option_patch


@callback(
    Output("row-pinning-bottom-2", "dashGridOptions"),
    Input("row-pinning-bottom-2", "virtualRowData"),
)
def row_pinning_bottom(data):
    dff = df2 if data is None else pd.DataFrame(data)
    sums = dff[["planStac", "factStac", "percentStac",
                "planStacHome", "factStacHome", "percentStacHome", ]].sum() if data else \
        {"planStac": 0, "factStac": 0, "percentStac": 0,
         "planStacHome": 0, "factStacHome": 0, "percentStacHome": 0}

    sum_formatted = {
        "planStac": sums['planStac'],
        "factStac": sums['factStac'],
        "percentStac": round(sums['factStac'] / sums['planStac'] * 100, 2) if sums['planStac'] != 0 else 0,
        "planStacHome": sums['planStacHome'],
        "factStacHome": sums['factStacHome'],
        "percentStacHome": round(sums['factStacHome'] / sums['planStacHome'] * 100, 2) if sums[
                                                                                              'planStacHome'] != 0 else 0,
    }
    grid_option_patch = Patch()
    grid_option_patch["pinnedBottomRowData"] = [{"Korpus": "Итого", **sum_formatted}]
    return grid_option_patch


@callback(
    Output("row-pinning-bottom-3", "dashGridOptions"),
    Input("row-pinning-bottom-3", "virtualRowData"),
)
def row_pinning_bottom(data):
    dff = df3 if data is None else pd.DataFrame(data)
    sums = dff[["planPN1", "factPN1", "percentPN1",
                "planDS2", "factDS2", "percentDS2", ]].sum() if data else \
        {"planPN1": 0, "factPN1": 0, "percentPN1": 0,
         "planDS2": 0, "factDS2": 0, "percentDS2": 0, }

    sum_formatted = {
        "planPN1": sums['planPN1'],
        "factPN1": sums['factPN1'],
        "percentPN1": round(sums['factPN1'] / sums['planPN1'] * 100, 2) if sums['planPN1'] != 0 else 0,
        "planDS2": sums['planDS2'],
        "factDS2": sums['factDS2'],
        "percentDS2": round(sums['factDS2'] / sums['planDS2'] * 100, 2) if sums['planDS2'] != 0 else 0,
    }
    grid_option_patch = Patch()
    grid_option_patch["pinnedBottomRowData"] = [{"Korpus": "Итого", **sum_formatted}]
    return grid_option_patch


@callback(
    Output("row-pinning-bottom-4", "dashGridOptions"),
    Input("row-pinning-bottom-4", "virtualRowData"),
)
def row_pinning_bottom(data):
    dff = df4 if data is None else pd.DataFrame(data)
    sums = dff[["planDV4", "factDV4", "percentDV4",
                "planDV2", "factDV2", "percentDV2",
                "planOPV", "factOPV", "percentOPV",
                "planUD1", "factUD1", "percentUD1",
                "planUD2", "factUD2", "percentUD2", ]].sum() if data else \
        {"planDV4": 0, "factDV4": 0, "percentDV4": 0,
         "planDV2": 0, "factDV2": 0, "percentDV2": 0,
         "planOPV": 0, "factOPV": 0, "percentOPV": 0,
         "planUD1": 0, "factUD1": 0, "percentUD1": 0,
         "planUD2": 0, "factUD2": 0, "percentUD2": 0, }

    sum_formatted = {
        "planDV4": sums['planDV4'],
        "factDV4": sums['factDV4'],
        "percentDV4": round(sums['factDV4'] / sums['planDV4'] * 100, 2) if sums['planDV4'] != 0 else 0,
        "planDV2": sums['planDV2'],
        "factDV2": sums['factDV2'],
        "percentDV2": round(sums['factDV2'] / sums['planDV2'] * 100, 2) if sums['planDV2'] != 0 else 0,
        "planOPV": sums['planOPV'],
        "factOPV": sums['factOPV'],
        "percentOPV": round(sums['factOPV'] / sums['planOPV'] * 100, 2) if sums['planOPV'] != 0 else 0,
        "planUD1": sums['planUD1'],
        "factUD1": sums['factUD1'],
        "percentUD1": round(sums['factUD1'] / sums['planUD1'] * 100, 2) if sums['planUD1'] != 0 else 0,
        "planUD2": sums['planUD2'],
        "factUD2": sums['factUD2'],
        "percentUD2": round(sums['factUD2'] / sums['planUD2'] * 100, 2) if sums['planUD2'] != 0 else 0,
    }
    grid_option_patch = Patch()
    grid_option_patch["pinnedBottomRowData"] = [{"Korpus": "Итого", **sum_formatted}]
    return grid_option_patch


if __name__ == "__main__":
    app.run(debug=True)
